os.loadAPI("/System/API/windows")
os.loadAPI("/System/API/sysbar")
os.loadAPI("/System/API/vedroid")
os.loadAPI("/System/API/contexts")
local xSize, ySize = term.getSize()
local xCenter = math.floor(xSize/2)
local yCenter = math.floor(ySize/2)
local r1, g1, b1 = term.getPaletteColor(8)
local r2, g2, b2 = term.getPaletteColor(16)
local r3, g3, b3 = term.getPaletteColor(64)
local page = 1
local projectF = ''
local projectName = ''
local xPos = 1
local sng = {}
local inst = 1
local insts = {'harp', 'bass', 'snare', 'hat', 'pling', 'basedrum', 'bell', 'chime', 'flute', 'guitar', 'xylophone'}
local objInsts = {}
local lenInst = 0
local stop = false
local lastProj = ''
for i=1,#insts do
	lenInst = lenInst+#insts[i]+1
end
local vol = 1
local pitch = 1
local temp = 100
local sampls = math.ceil(xSize/6)
local road = window.create(term.current(),1,3,sampls*6,9)
road.setPaletteColor(8,220,220,220)
road.setPaletteColor(16,230,230,230)
road.setPaletteColor(64,236,236,236)


local clear = function(color)
	term.setBackgroundColor(color)
	term.clear()
	term.setCursorPos(1,1)
end

local text = function(window,string,xPos,yPos)
	window.setCursorPos(xPos,yPos)
	window.write(string)
end

local drawBox = function(window,char,x1,y1,x2,y2,color)
	window.setBackgroundColor(color)
	for i=x1,x2 do
		for j=y1,y2 do
			window.setCursorPos(i,j)
			window.write(char)
		end
	end
end

local pastebin = function(paste,filename)
	local file = http.get("http://pastebin.com/raw.php?i="..paste)
	if file then
		file = file.readAll()
		h=fs.open(filename,"w")
		h.write(file)
		h.close()
	else
		windows.error("Unable to connect to the Internet")
	end
end

local sysBar = function()
	sysbar.header("Starship",colors.red,colors.black)
	if page == 2 then
		term.setTextColor(colors.lightGray)
		text(term,'Play ',10,1)
		term.write('File ')
		term.setTextColor(colors.white)
		text(term,projectName,xSize-#projectName+1,1)
	end
end

local function settings()
	term.setTextColor(colors.white)
	term.setBackgroundColor(colors.black)
	text(term,string.char(15)..': ',1,13)
	local lng = 3
	for i=1,#insts do
		if i == inst then
			term.setTextColor(colors.red)
		else
			term.setTextColor(colors.gray)
		end
		lng = lng + #insts[i] + 1
		if lng > xSize then
			term.setCursorPos(4,14)
			lng = 3
		end
		term.write(insts[i]..' ')
	end
	
	term.setTextColor(colors.white)
	term.setBackgroundColor(colors.black)
	text(term,'Pitch:  ',1,16)
	drawBox(term,' ',9,16,18,16,16)
	term.setTextColor(colors.gray)
	text(term,string.char(17),10,16)
	text(term,string.char(16),17,16)
	drawBox(term,' ',12,16,15,16,8)
	term.setTextColor(colors.red)
	text(term,pitch,13,16)
	
	term.setTextColor(colors.white)
	term.setBackgroundColor(colors.black)
	text(term,'Volume: ',1,18)
	for i=0,3 do
		if i == vol then
			term.setTextColor(colors.red)
			term.setBackgroundColor(8)
		else
			term.setTextColor(colors.gray)
			term.setBackgroundColor(16)
		end
		term.write(' '..i..' ')
	end
	
	term.setTextColor(colors.white)
	term.setBackgroundColor(colors.black)
	text(term,'Temp: ',36,17)
	drawBox(term,' ',42,16,50,18,16)
	term.setTextColor(colors.lightGray)
	text(term,temp,45,17)
	term.setTextColor(colors.gray)
	text(term,string.char(16),49,17)
	text(term,string.char(17),43,17)
end

local function play()
	
	local last = 0
	local speaker = peripheral.find('speaker')
	
	if speaker then
		stop = false
		speaker.maxNotesPerTick = 8
		local wait = 10/sng[1]['temp']
		for i=0,sampls do
			road.redraw()
			if stop then
				break
			end
			if i*6+xPos+5 > xSize then
				xPos = xSize-(i*6+5)
				road.reposition(xPos,3)
			end
			drawBox(term,' ',i*6+xPos,11,i*6+5+xPos,11,colors.cyan)
			term.setTextColor(colors.white)
			text(term,i+1,i*6+xPos+3-math.floor(#tostring(i)/2),11)
			if sng[2][i] then
			
				last = i
				local function pl1()
					if sng[2][i][1] and sng[2][i][1]['instrument'] then
						speaker.playNote(sng[2][i][1]['instrument'],sng[2][i][1]['volume'],sng[2][i][1]['pitch'])
					end
				end
				
				local function pl2()
					if sng[2][i][2] and sng[2][i][2]['instrument'] then
						speaker.playNote(sng[2][i][2]['instrument'],sng[2][i][2]['volume'],sng[2][i][2]['pitch'])
					end
				end
				
				local function pl3()
					if sng[2][i][3] and sng[2][i][3]['instrument'] then
						speaker.playNote(sng[2][i][3]['instrument'],sng[2][i][3]['volume'],sng[2][i][3]['pitch'])
					end
				end
				
				local function pl4()
					if sng[2][i][4] and sng[2][i][4]['instrument'] then
						speaker.playNote(sng[2][i][4]['instrument'],sng[2][i][4]['volume'],sng[2][i][4]['pitch'])
					end
				end
				
				local function pl5()
					if sng[2][i][5] and sng[2][i][5]['instrument'] then
						speaker.playNote(sng[2][i][5]['instrument'],sng[2][i][5]['volume'],sng[2][i][5]['pitch'])
					end
				end
				
				local function pl6()
					if sng[2][i][6] and sng[2][i][6]['instrument'] then
						speaker.playNote(sng[2][i][6]['instrument'],sng[2][i][6]['volume'],sng[2][i][6]['pitch'])
					end
				end
				
				local function pl7()
					if sng[2][i][7] and sng[2][i][7]['instrument'] then
						speaker.playNote(sng[2][i][7]['instrument'],sng[2][i][7]['volume'],sng[2][i][7]['pitch'])
					end
				end
				
				local function pl8()
					if sng[2][i][8] and sng[2][i][8]['instrument'] then
						speaker.playNote(sng[2][i][8]['instrument'],sng[2][i][8]['volume'],sng[2][i][8]['pitch'])
					end
				end
				
				parallel.waitForAll(pl1,pl2,pl3,pl4,pl5,pl6,pl7,pl8)
			end
			sleep(wait)
		end
		if not stop then
			sampls = last+1
			sng[1]['length'] = sampls
		end
		road.redraw()
	else
		windows.error('There are no connected speakers')
		clear(colors.black)
		sysBar()
		road.redraw()
		settings()
	end
end

local function stoper()
	while true do
		local event, side, x, y = os.pullEvent()
		if event == "mouse_click" and x>=10 and x<=13 and y==1 then
			stop = true
			road.redraw()
			break
		end
	end
end

local redraw = function()
	clear(colors.black)
	if page == 1 then
		lastProj=''
		term.setTextColor(colors.white)
		text(term,'New Project',2,3)
		text(term,'Open Project',2,5)
		text(term,'Exit',2,ySize-3)
		projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/lastproject.cfg','r')
		if projectF then
			lastProj = projectF.readAll()
			projectF.close()
			term.setTextColor(colors.lightGray)
			text(term,'Last Project: ',2,8)
			term.write(lastProj)
		end
		term.setTextColor(colors.gray)
		text(term,'Let\'s get into outer ',1,ySize)
		term.setTextColor(colors.red)
		term.write('space')
	elseif page == 2 then
		local j = 0
		local k = 1
		local clr = 8
		term.setTextColor(colors.white)
		
		settings()
		
		drawBox(road,' ',1,9,sampls*6,9,64)
		road.setTextColor(8)
		for i=1,sampls+1 do
			drawBox(road,' ',i*6-5,1,i*6,8,clr)
			if clr == 8 then
				clr = 16
			else
				clr = 8
			end
			road.setBackgroundColor(64)
			text(road,i,i*6-2-math.floor(#tostring(i)/2),9)
		end
	end
	sysBar()
end


local running = function()
	while true do
		event, side, x, y = os.pullEvent()
		if event == "mouse_click" then
			if page ==2 and x>=15 and x<=18 and y==1 then
				local ans = contexts.main(15,1,'Save','Rename','','Clear','','Menu','Exit')
				if ans == 'Exit' then
					home = true
					break
				elseif ans == 'Save' then
					projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/'..projectName..'.sspro','w')
					if projectF then
						projectF.write(textutils.serialize(sng))
						projectF.close()
						windows.attention('Success','Project saved')
					else
						windows.error('Unable to open file')
					end
					clear(colors.black)
					sysBar()
					road.redraw()
					settings()
				elseif ans == 'Rename' then
					local name = windows.input("auto","auto",'Enter Project Name',30,{'',''})
					if name[1] ~= nil and name[1] ~= '' and #name[1] > 0 then
						local fl = fs.list('.ds/'..l_login..'/Starship.apk/Resources')
						local find = false
						for i=1,#fl do
							if name[1]..'.sspro' == fl[i] then
								find = true
								break
							end
						end
						if find then
							clear(colors.black)
							sysBar()
							road.redraw()
							settings()
							local inp = windows.select({"This Project already exists"},{"Do you want to rewrite it?"},{"Yes",colors.red,colors.white},{"No",colors.blue,colors.white})
							if inp == 'Yes' then
								find = false
							end
						end
						if not find then
							projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/'..name[1]..'.sspro','w')
							if projectF then
								projectF.write(textutils.serialize(sng))
								projectF.close()
								fs.delete('.ds/'..l_login..'/Starship.apk/Resources/'..projectName..'.sspro')
								projectName = name[1]
								windows.attention('Success','Project renamed')
							else
								windows.error('Unable to open file')
							end
							clear(colors.black)
							sysBar()
							road.redraw()
							settings()
						end
					end
				elseif ans == 'Clear' then
					local q = windows.select({"Clear this Project"},{"Are you sure?"},{"Yes",colors.red,colors.white},{"No",colors.blue,colors.white})
					if q == 'Yes' then
						temp = 100
						sampls = math.ceil(xSize/6)
						sng = {{temp = temp,length = sampls},{}}
						road.reposition(1,3,sampls*6,9)
						xPos = 1
						inst = 1
						vol = 1
						pitch = 1
						redraw()
					else
						projectName = ''
						clear(colors.black)
						sysBar()
						road.redraw()
						settings()
					end
				elseif ans == 'Menu' then
					sng = {}
					page = 1
					redraw()
				else
					sysBar()
					road.redraw()
				end
			elseif page == 1 then
				if y == 3 then
					paintutils.drawLine(1,3,xSize,3,8)
					text(term,'New Project',2,3)
					sleep(0.1)
					redraw()
					local name = windows.input("auto","auto",'Enter Project Name',30,{'',''})
					if name[1] ~= nil and name[1] ~= '' and #name[1] > 0 then
						local fl = fs.list('.ds/'..l_login..'/Starship.apk/Resources')
						local find = false
						for i=1,#fl do
							if name[1]..'.sspro' == fl[i] then
								find = true
								redraw()
								break
							end
						end
						if find then
							local inp = windows.select({"This Project already exists"},{"Do you want to rewrite it?"},{"Yes",colors.red,colors.white},{"No",colors.blue,colors.white})
							if inp == 'Yes' then
								find = false
							end
						end
						if not find then
							page = 2
							temp = 100
							sampls = math.ceil(xSize/6)
							sng = {{temp = temp,length = sampls},{}}
							projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/'..name[1]..'.sspro','w')
							projectF.write(textutils.serialize(sng))
							projectF.close()
							projectName = name[1]
							projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/lastproject.cfg','w')
							projectF.write(projectName)
							projectF.close()
							road.reposition(1,3,sampls*6)
							xPos = 1
							inst = 1
							vol = 1
							pitch = 1
						end
					end
					redraw()
				elseif y == 5 then
					paintutils.drawLine(1,5,xSize,5,8)
					text(term,'Open Project',2,5)
					sleep(0.1)
					redraw()
					local name = windows.input("auto","auto",'Enter Project Name',30,{'',''})
					if name[1] ~= nil and name[1] ~= '' and #name[1] > 0 then
						local fl = fs.list('.ds/'..l_login..'/Starship.apk/Resources')
						local find = false
						for i=1,#fl do
							if name[1]..'.sspro' == fl[i] then
								find = true
								redraw()
								break
							end
						end
						if not find then
							windows.error('This Project doesn\'t exist')
							redraw()
						elseif find then
							projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/'..name[1]..'.sspro','r')
							sng = textutils.unserialize(projectF.readAll())
							projectF.close()
							projectName = name[1]
							projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/lastproject.cfg','w')
							projectF.write(projectName)
							projectF.close()
							page = 2
							temp = sng[1]['temp']
							sampls = sng[1]['length']
							road.reposition(1,3,sampls*6+6,9)
							xPos = 1
							inst = 1
							vol = 1
							pitch = 1
							redraw()
							for i=0,sampls do
								if sng[2][i] then
									local crs = 16
									if i%2 == 0 then
										crs = 8
									end
									road.setTextColor(crs)
									for f=1,8 do
										if sng[2][i][f] and sng[2][i][f]['instrument'] then
											local ins = 1
											for j=1,#insts do
												if insts[j] == sng[2][i][f]['instrument'] then
													ins = j
													break
												end
											end
											local ni = string.sub(insts[ins],1,1)..string.sub(insts[ins],#insts[ins])
											drawBox(road,' ',i*6+1,f,i*6+6,f,colors.red)
											text(road,string.char(22)..ni..sng[2][i][f]['pitch'],i*6+1,f)
											text(road,sng[2][i][f]['volume'],i*6+6,f)
										end
									end
								end
							end
						end
					else
						redraw()
					end
				elseif y==8 and lastProj~='' then
					paintutils.drawLine(1,8,xSize,8,8)
					text(term,'Last Project: '..lastProj,2,8)
					sleep(0.1)
					projectF = fs.open('.ds/'..l_login..'/Starship.apk/Resources/'..lastProj..'.sspro','r')
					sng = textutils.unserialize(projectF.readAll())
					projectF.close()
					projectName = lastProj
					page = 2
					temp = sng[1]['temp']
					sampls = sng[1]['length']
					road.reposition(1,3,sampls*6+6,9)
					xPos = 1
					inst = 1
					vol = 1
					pitch = 1
					redraw()
					for i=0,sampls do
						if sng[2][i] then
							local crs = 16
							if i%2 == 0 then
								crs = 8
							end
							road.setTextColor(crs)
							for f=1,8 do
								if sng[2][i][f] and sng[2][i][f]['instrument'] then
									local ins = 1
									for j=1,#insts do
										if insts[j] == sng[2][i][f]['instrument'] then
											ins = j
											break
										end
									end
									local ni = string.sub(insts[ins],1,1)..string.sub(insts[ins],#insts[ins])
									drawBox(road,' ',i*6+1,f,i*6+6,f,colors.red)
									text(road,string.char(22)..ni..sng[2][i][f]['pitch'],i*6+1,f)
									text(road,sng[2][i][f]['volume'],i*6+6,f)
								end
							end
						end
					end
				elseif y == ySize-3 then
					paintutils.drawLine(1,ySize-3,xSize,ySize-3,8)
					text(term,'Exit',2,ySize-3)
					sleep(0.1)
					break
				end
			elseif page == 2 then
				if x>=10 and x<=13 and y==1 then
					term.setTextColor(colors.cyan)
					term.setBackgroundColor(colors.black)
					text(term,'Stop ',10,1)
					parallel.waitForAny(play,stoper)
					term.setTextColor(colors.lightGray)
					term.setBackgroundColor(colors.black)
					text(term,'Play ',10,1)
				elseif x>=4 and ((x<=2+lenInst and lenInst < xSize) or x < xSize) and y== 13 then
					local tx = 3
					local i = 0
					while i<#insts and tx < x do
						i=i+1
						tx = tx + #insts[i]+1
					end
					inst = i
					settings()
				elseif x>=4 and x <= 7+lenInst - xSize and y== 14 then
					local tx = 3
					local i = 0
					while i<#insts and tx < xSize + x-4 do
						i=i+1
						tx = tx + #insts[i]+1
					end
					inst = i
					settings()
				elseif x>=42 and x<=43 and y>=16 and y<=18 then
					if temp > 10 then
						term.setBackgroundColor(16)
						temp = temp - 10
						sng[1]['temp'] = temp
						term.setTextColor(colors.red)
						text(term,string.char(17),43,17)
						sleep(0.1)
						settings()
					end
				elseif x>=49 and x<=50 and y>=16 and y<=18 then
					if temp < 330 then
						term.setBackgroundColor(16)
						temp = temp + 10
						sng[1]['temp'] = temp
						term.setTextColor(colors.red)
						text(term,string.char(16),49,17)
						sleep(0.1)
						settings()
					end
				elseif x>=9 and x<=20 and y==18 then
					vol = math.floor((x-6)/3)-1
					settings()
				elseif x>=9 and x<=11 and y==16 and pitch > 0 then
					pitch = pitch - 1
					term.setBackgroundColor(16)
					term.setTextColor(colors.red)
					text(term,string.char(17),10,16)
					sleep(0.1)
					settings()
				elseif x>=16 and x<=18 and y==16 and pitch < 24 then
					pitch = pitch + 1
					term.setBackgroundColor(16)
					term.setTextColor(colors.red)
					text(term,string.char(16),17,16)
					sleep(0.1)
					settings()
				elseif y>=3 and y<=11 then
					local xs = math.floor((x-xPos)/6)*6+1
					local xe = xs + 5
					local crs = 16
					if math.floor((x-xPos)/6)%2 == 0 then
						crs = 8
					end
					if not sng[2][math.floor((x-xPos)/6)] then
						sng[2][math.floor((x-xPos)/6)] = {}
					end
					sng[2][math.floor((x-xPos)/6)][y-2] = {}
					if side == 1 then
						road.setTextColor(crs)
						drawBox(road,' ',xs,y-2,xe,y-2,colors.red)
						local ni = string.sub(insts[inst],1,1)..string.sub(insts[inst],#insts[inst])
						text(road,string.char(22)..ni..pitch,xs,y-2)
						text(road,vol,xe,y-2)
						sng[2][math.floor((x-xPos)/6)][y-2]['instrument'] = insts[inst]
						sng[2][math.floor((x-xPos)/6)][y-2]['volume'] = vol
						sng[2][math.floor((x-xPos)/6)][y-2]['pitch'] = pitch
						if math.floor((x-xPos)/6) > sampls then
							sampls = math.floor((x-xPos)/6)
							sng[1]['length'] = sampls
						end
					elseif side == 2 then
						drawBox(road,' ',xs,y-2,xe,y-2,crs)
					end
				end
			end
		elseif event == 'mouse_scroll' then
			if side == 1 --[[and xPos > -396+xSize]] then
				xPos = xPos - 1
				if sampls*6 < xSize-xPos then
					sampls=sampls+1
					sng[1]['length'] = sampls
					road.reposition(xPos,3,sampls*6,9)
					local clr = 8
					if sampls % 2 == 0 then
						clr = 16
					end
					drawBox(road,' ',sampls*6-5,1,sampls*6,8,clr)
					drawBox(road,' ',sampls*6-5,9,sampls*6,9,64)
					road.setTextColor(8)
					text(road,sampls,(sampls-1)*6+4-math.floor(#tostring(sampls)/2),9)
				else
					road.reposition(xPos,3)
				end
			elseif side == -1 and xPos < 1 then
				xPos = xPos + 1
				road.reposition(xPos,3)
				if xPos > 1 then
					xPos = 1
				end
			end
		end
	end
end

redraw()
running()
road.setPaletteColor(8,r1,g1,b1)
road.setPaletteColor(16,r2,g2,b2)
road.setPaletteColor(64,r3,g3,b3)
road = nil